package com.siqi.hr.system.organization.service;

import com.siqi.hr.common.Constants;
import com.siqi.hr.common.redis.RedisAPI;
import com.siqi.hr.common.utils.Const;
import com.siqi.hr.system.common.dao.intf.CommonOperationDao;
import com.siqi.hr.system.organization.dao.intf.DeptDao;
import com.siqi.hr.system.organization.dao.intf.EmployeeDao;
import com.siqi.hr.system.organization.entity.Dept;
import com.siqi.hr.system.organization.entity.EmpReDept;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 部门信息维护service
 * @author  xiaoxm
 * Created by xiaoxm on 2016/8/5.
 */
@Service("deptService")
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public class DeptService {

    @Autowired
    private DeptDao deptDao;
    @Autowired
    private CommonOperationDao commonOperationDao;
    @Autowired
    private EmployeeDao employeeDao;

    /**
     * 根据id获取部门
     * @param     tableName   表名
     * @param     id           组织id
     * @author ChenL
     */
    public Dept getById(String tableName,String id){
        Dept dept = deptDao.getById(tableName,id);
        return dept;
    }

    /**
     * 根据父级部门id获取所有子部门数据
     * @author    xiaogq
     * @param     depTableName   部门(组织表名)
     * @return
     */
    public JSONArray queryDeptTree(String depTableName) throws Exception {
        JSONArray dataArray = new JSONArray();
        List<Dept> deptAllDatas = this.queryAllDept(depTableName);
        Map<Long,String> deptMap = new HashMap<Long, String>();
        for(Dept dept : deptAllDatas){
            deptMap.put(dept.getId().longValue(),dept.getName());
        }
        for(Dept dept : deptAllDatas){
            JSONObject obj = new JSONObject();
            obj.put("id",dept.getId());
            obj.put("pId",dept.getParent() == null ? "0" : dept.getParent().getId());
            obj.put("deptRank",dept.getDeptRank());
            List<String> deptIds = Arrays.asList(dept.getDeptRank().split(","));
            List<String> deptNames = new ArrayList<String >();
            for(String deptIdStr:deptIds){
                String deptName = deptMap.get(Long.parseLong(deptIdStr));
                deptNames.add(deptName);
            }
            String deptNameRank = StringUtils.join(deptNames,"-");
            obj.put("deptNameRank",deptNameRank);
            obj.put("name",dept.getName());
            dataArray.add(obj);
        }
        return dataArray;
    }

    /**
     * 查询所有部门
     * @author ChenL
     */
    public List<Dept> queryAllDept(String tableName){
        return deptDao.queryAllDept(tableName);
    }

    /**
     *获取部门数据列表
     * @param tableName   实体表名
     * @param deptIdList
     * @param flag        是否显示人数(true:显示，false:不显示)
     * @return
     */
    public JSONArray queryDeptTree(String tableName,String empDeptTableName,String empTableName,List<Long> deptIdList,boolean flag) throws Exception{
        JSONArray dataArray = new JSONArray();
        List<Dept> deptAllDatas = this.queryAllDept(tableName);
        List<Map<String, Object>> users = employeeDao.queryRelationUsers(tableName, empDeptTableName, empTableName);
        for(Dept dept : deptAllDatas){
            int alreadyPeople = 0;
            for(Map<String, Object> map : users){
                String deptIds = map.get("u_dept_id") != null ? map.get("u_dept_id").toString() : "";
                if(StringUtils.isNotBlank(deptIds)){
                    if(deptIds.indexOf("," + dept.getId() +",") != -1){
                        alreadyPeople++;
                    }
                }
            }
            JSONObject obj = new JSONObject();
            obj.put("id",dept.getId());
            obj.put("pId",dept.getParent() == null ? "0" : dept.getParent().getId());
            obj.put("deptRank",dept.getDeptRank());
            //obj.put("deptName",dept.getName());
            if(flag){
                obj.put("name",dept.getName()+"("+dept.getPlaitPeople()+"/"+alreadyPeople+"人)");
            }else{
                obj.put("name",dept.getName());
            }
            if(deptIdList != null && deptIdList.contains(dept.getId())){
                obj.put("checked",true);
            }
            //如果已编制人数大于总编制人数
            if(alreadyPeople > dept.getPlaitPeople()){
                obj.put("color","red");
            }else{
                obj.put("color","default");
            }
            if(dept.getId() == Long.valueOf(Constants.ROOTDEPTID)){//控制节点是否可以移动
                obj.put("drag",false);
            }else{
                obj.put("drag",true);
            }
            //obj.put("isParent",dept.getIsParent());
            obj.put("font","{'font-size': 'large'}");
            dataArray.add(obj);
        }
        return dataArray;
    }

    /**
     * 添加部门(组织)信息
     * @param tableName           组织表名
     * @param dept                 组织对象
     * @param deptRank            部门等级编码字符串
     * @return
     * @throws Exception
     */
    public JSONObject saveAddDeptDatas(String tableName,Dept dept,String deptRank) throws Exception{
        JSONObject obj = new JSONObject();
        String deptName = dept.getName();
        boolean flag = deptDao.isRepeatDeptName(0L,deptName,tableName);
        if(flag){
            obj.put("flag","部门名称不能重复!");
        }else{
            long deptId = deptDao.saveAddDept(tableName,dept);
            if(deptId > 0){
                obj.put("flag","success");
                deptRank += deptId+",";
                deptDao.updateDeptRankById(tableName,deptId,deptRank);
                obj.put("id",deptId);
                obj.put("name",deptName);
                obj.put("deptRank",deptRank);
            }else{
                obj.put("flag","添加(部门)组织信息失败!");
            }
        }
        return obj;
    }

    /**
     * 批量添加部门信息
     * @author ChenL
     */
    public void batchAddDepts(String deptTableName,List<Dept> deptList) throws Exception{
        deptDao.batchAddDept(deptTableName,deptList);
    }

    /**
     * 编辑保存部门(组织)信息
     * @param tableName           组织表名
     * @param dept                 组织对象
     * @throws Exception
     */
    public JSONObject saveEditDeptDatas(String tableName,Dept dept) throws Exception{
        JSONObject obj = new JSONObject();
        String deptName = dept.getName();
        boolean flag = deptDao.isRepeatDeptName(dept.getId(),deptName,tableName);
        if(flag){
            obj.put("flag","部门名称不能重复!");
        }else{
            int counts = deptDao.saveEditDept(tableName,dept);
            if(counts > 0){
                obj.put("flag","success");
            }else{
                obj.put("flag","编辑(部门)组织信息失败!");
            }
        }
        return obj;
    }

    /**
     * 通过部门员工关系表检查主管是否在所设置部门中，不在则更新主管部门
     * @author ChenL
     */
    public void updateMangerDept(List<String> managerList,Long deptId,String zEmpDeptTableName) throws Exception{
        for (String manager:managerList) {
            long count = deptDao.countByRelation(zEmpDeptTableName,manager,deptId.toString());
            if(count == 0l){
                commonOperationDao.addZDate(zEmpDeptTableName,manager,deptId.toString(),false);
            }
        }
    }

    /**
     * 删除部门数据
     * @param tableName（表名)
     * @param pId   （父级部门id）
     * @param dataId（数据id）
     * @throws Exception
     */
    public JSONObject deleteDept(String tableName,String pId, String dataId) throws Exception{
        JSONObject obj = new JSONObject();
        boolean bol = deptDao.isChildrenNodes(tableName,dataId);
        if(bol){//如果有子部门
            obj.put("flag","当前节点有子部门不能删除!");
        }else{
            //删除数据时该记录是否被其他表引用
            JSONArray quoteArray = new JSONArray();
            String quoteList = RedisAPI.get(tableName,Constants.DEFAULTDB_INDEX);
            if(StringUtils.isNotBlank(quoteList)){
                quoteArray = JSONArray.fromObject(quoteList);
            }else{
                quoteArray = commonOperationDao.getAllQuoteTableInfo(tableName);
            }
            List<Map<String,Object>> resultList = commonOperationDao.isQuoteByOtherTable(quoteArray,dataId);
            if(resultList.size() > 0){
                obj.put("flag","改记录以及被其他实体引用,不能删除!");
            }else{
                obj.put("flag","true");
                deptDao.delDept(tableName,dataId);
            }
        }
        return obj;
    }

    /**
     * 部门(组织)节点移动方法
     * @param  ids    移动部门id
     * @param  pId    移动目标部门id
     * @param  pdeptRank    移动目标部门等级
     * @throws Exception
     */
    public JSONObject moveDept(String tableName,String ids, String pId,String pdeptRank, String oriDeptRank) throws Exception{
        JSONObject obj = new JSONObject();
        int counts = deptDao.updateDeptPidById(tableName,ids,pId,pdeptRank, oriDeptRank);
        obj.put("flag",counts > 0);
        return obj;
    }

    /**
     * 获取根部门
     * @param deptTableName    部门表名称
     * @author ChenL
     */
    public Dept queryRootDept(String deptTableName) throws Exception{
        return deptDao.queryRootDept(deptTableName);
    }

    public void updateDeptOrders(String tableName, String orderIds){
        deptDao.updateDeptOrders(tableName, orderIds);
    }

    /**
     * 根据员工id查询相关部门
     * @param empReDept     员工相关部门对象
     * @return
     */
    public Map<String,Object> queryEmpRelateDeptAll(EmpReDept empReDept){
        Map<String,Object> resultMap = new HashMap<String,Object>();
        List<Map<String,Object>>  rows = deptDao.queryEmpRelateDeptAll(empReDept);
        int totals = deptDao.queryEmpRelateDeptCountAll(empReDept);
        resultMap.put(Const.ROWS, rows);
        resultMap.put(Const.TOTAL, totals);
        return resultMap;
    }

    /**
     * 根据id删除员工部门关系记录
     * @author   xioagq
     * @param    rId        员工与部门相关关系表id
     * @return
     */
    public JSONObject delEmpRelateDept(String rId){
        JSONObject obj = new JSONObject();
        int counts = deptDao.delEmpRelateDept(rId);
        obj.put("flag",counts > 0);
        return obj;
    }

}
